﻿using D.AT.Extensions;
using D.AT.Models;
using System.Data;
using D.AT.Dto;
using D.AT.UIUitl;
using D.AT.HttpUtil;
using D.AT.Events;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;
using System.Text;
using NLog;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Collections.Generic;
using System;
using System.Web;
using D.AT.NLogsUtil;

namespace D.AT
{
    public partial class FrmSetting : Form
    {

        private List<SPCContextKeyEntity> contextKeyList = new List<SPCContextKeyEntity>();

        public FrmSetting()
        {
            InitializeComponent();
            this.dgvExclude.SetGridDataViewStyle();
            this.dgvProcess.SetGridDataViewStyle();
            this.dgvExclude.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.ColumnHeader;
            this.dgvExclude.CellContentClick += DgvExclude_CellContentClick;

            this.cboLds.SelectedValueChanged += CboLds_SelectedValueChanged;
            this.checkStandardForXbar.CheckedChanged += CheckStandardForXbar_CheckedChanged;
            this.checkStandardForTREND.CheckedChanged += CheckStandardForTREND_CheckedChanged;
            this.checkStandardForR.CheckedChanged += CheckStandardForR_CheckedChanged;
            this.checkStandardForS.CheckedChanged += CheckStandardForS_CheckedChanged;

            this.dgvProcess.CellContentClick += dgvProcess_CellContentClick;
            this.btnLook.Click += btnLook_Click;
        }

        #region 勾选使用MES的Spec Limit


        private void CheckStandardForXbar_CheckedChanged(object? sender, EventArgs e)
        {
            if (checkStandardForXbar.Checked)
            {
                this.txtUSLForXbar.Text = "";
                this.txtTargetForXbar.Text = "";
                this.txtLSLForXbar.Text = "";
                this.txtUSLForXbar.Enabled = false;
                this.txtTargetForXbar.Enabled = false;
                this.txtLSLForXbar.Enabled = false;
            }
            else
            {
                this.txtUSLForXbar.Text = "1000";
                this.txtTargetForXbar.Text = "500";
                this.txtLSLForXbar.Text = "100";
                this.txtUSLForXbar.Enabled = true;
                this.txtTargetForXbar.Enabled = true;
                this.txtLSLForXbar.Enabled = true;
            }
        }

        private void CheckStandardForTREND_CheckedChanged(object? sender, EventArgs e)
        {
            if (checkStandardForTREND.Checked)
            {
                this.txtUSLForTREND.Text = "";
                this.txtTargetForTREND.Text = "";
                this.txtLSLForTREND.Text = "";
                this.txtUSLForTREND.Enabled = false;
                this.txtTargetForTREND.Enabled = false;
                this.txtLSLForTREND.Enabled = false;
            }
            else
            {
                this.txtUSLForTREND.Text = "1000";
                this.txtTargetForTREND.Text = "500";
                this.txtLSLForTREND.Text = "100";
                this.txtUSLForTREND.Enabled = true;
                this.txtTargetForTREND.Enabled = true;
                this.txtLSLForTREND.Enabled = true;
            }
        }

        private void CheckStandardForS_CheckedChanged(object? sender, EventArgs e)
        {
            if (checkStandardForS.Checked)
            {
                this.txtUSLForS.Text = "";
                this.txtTargetForS.Text = "";
                this.txtLSLForS.Text = "";
                this.txtUSLForS.Enabled = false;
                this.txtTargetForS.Enabled = false;
                this.txtLSLForS.Enabled = false;
            }
            else
            {
                this.txtUSLForS.Text = "1000";
                this.txtTargetForS.Text = "500";
                this.txtLSLForS.Text = "100";
                this.txtUSLForS.Enabled = true;
                this.txtTargetForS.Enabled = true;
                this.txtLSLForS.Enabled = true;
            }
        }

        private void CheckStandardForR_CheckedChanged(object? sender, EventArgs e)
        {
            if (checkStandardForR.Checked)
            {
                this.txtUSLForR.Text = "";
                this.txtTargetForR.Text = "";
                this.txtLSLForR.Text = "";
                this.txtUSLForR.Enabled = false;
                this.txtTargetForR.Enabled = false;
                this.txtLSLForR.Enabled = false;
            }
            else
            {
                this.txtUSLForR.Text = "1000";
                this.txtTargetForR.Text = "500";
                this.txtLSLForR.Text = "100";
                this.txtUSLForR.Enabled = true;
                this.txtTargetForR.Enabled = true;
                this.txtLSLForR.Enabled = true;
            }
        }
        #endregion

        /// <summary>
        /// 加载数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void FrmSetting_Load(object sender, EventArgs e)
        {
            this.LoadColumn();
            this.LoadProcessColumn();
            LoadUiData();
            await LoadEnvAsync();
        }

        private async void LoadUiData()
        {
             
            this.cboEdcLevel.Items.Clear();
            this.cboEdcLevel.Items.Add("SITE");
            this.cboEdcLevel.Items.Add("WAFER");
            this.cboEdcLevel.Items.Add("LOT");
            this.cboEdcLevel.Items.Add("BATCH");
            this.cboEdcLevel.Text = "WAFER";

            this.cboContinueUni.Items.Clear();
            this.cboContinueUni.Items.Add("分钟");
            this.cboContinueUni.Items.Add("次");
            this.cboContinueUni.Text = "分钟";

            this.checkCreateSubJob.Checked = true;
            this.checkKeyChart.Checked = true;
            this.checkRule.Checked = true;

            this.checkOOS.Checked = true;
            this.checkOOW.Checked = true;
            this.checkWE1.Checked = true;
            this.checkSOOW.Checked = true;
            this.checkSOOS.Checked = true;

            this.txtUSLForXbar.Text = "1000";
            this.txtTargetForXbar.Text = "500";
            this.txtLSLForXbar.Text = "100";
            this.txtUCLForXbar.Text = "800";
            this.txtCLForXbar.Text = "500";
            this.txtLCLForXbar.Text = "300";

            this.txtUSLForTREND.Text = "1000";
            this.txtTargetForTREND.Text = "500";
            this.txtLSLForTREND.Text = "100";
            this.txtUCLForTREND.Text = "800";
            this.txtCLForTREND.Text = "500";
            this.txtLCLForTREND.Text = "300";

            this.txtUSLForR.Text = "1000";
            this.txtTargetForR.Text = "500";
            this.txtLSLForR.Text = "-100";
            this.txtUCLForR.Text = "800";
            this.txtCLForR.Text = "500";
            this.txtLCLForR.Text = "-50";

            this.txtUSLForS.Text = "1000";
            this.txtTargetForS.Text = "500";
            this.txtLSLForS.Text = "-100";
            this.txtUCLForS.Text = "800";
            this.txtCLForS.Text = "500";
            this.txtLCLForS.Text = "-50";

            this.txtTotalChartCount.Value = 10;

            this.checkStandardForXbar.Checked = false;
            this.checkStandardForTREND.Checked = false;
            this.checkStandardForR.Checked = false;
            this.checkStandardForS.Checked = false;

            this.txtJson.Text = httpJson;
        }

        private string httpJson = @"{
	""testFlag"": false,
	""sampleDate"": ""{{sampleDate}}"",
	""ldsId"": {{ldsId}},
	""fabId"": ""{{fabId}}"",
	""standardSamples"": [{
    ""dcItemName"": ""{{dcItemName}}"",
		""unit"": ""unit"",
		""limit"": {
			""specLimitLower"": """",
			""specLimitUpper"": """",
			""targetValue"": """",
			""clValue"": """",
			""controlLimitLower"": """",
			""controlLimitUpper"": """"
		},
		""type"": ""Raw"",
		""addedKeys"": [{{addedKeys}}],
		""masterKeys"": [{{masterKeys}}],
		""rawValues"": {{rawValues}}
	}],
	""attributeSample"": []
}";
        private string corbaJson = @"
{
  ""lotType"": ""Offline"",
  ""dcSpecID"": {
    ""identifier"": ""DCSID-1001"",
    ""stringifiedObjectReference"":""""
  },
  ""processTimestamp"": ""{{processTimestamp}}"",
  ""measurementTimestamp"": ""{{measurementTimestamp}}"",
  ""processProcessDefinitionID"": {
    ""identifier"": ""PD_P_IBM02.00"",
    ""stringifiedObjectReference"":""""
  },
  ""ocapNo"": """",
  ""batchLots"": [
		{
			""strHashedInfoSeq"": [],
			""boatSlotNo"": """",
			""lotID"": {
				""identifier"": ""FP000008.07"",
				""stringifiedObjectReference"": ""SPIORLL:N:P16/#PosLot#F16#5645ncxsg6c_s7gbmj""
			}
		}
],
  ""pmTag"": """",
  ""siInfo"": {},
  ""productID"": {
    ""identifier"": ""PROD_IBM01.00"",
    ""stringifiedObjectReference"":""""
  },
  ""mainProcessDefinitionID"": {
    ""identifier"": ""MainPD_IBM01.00"",
    ""stringifiedObjectReference"":""""
  },
  
  ""equipmentMonitorID"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""lotID"": {
    ""identifier"": ""PP000013.00"",
    ""stringifiedObjectReference"":""""
  },
  ""measurementRecipe"": {
    ""identifier"": ""IBM.RCP_M01.00"",
    ""stringifiedObjectReference"":""""
  },
  ""subLotType"": ""PP"",
  ""reworkFlag"": ""N"",
  ""ocapActionType"": """",
  ""processEquipmentArea"": ""SYSTEM"",
  ""ownerUserID"": {
    ""identifier"": ""SPC"",
    ""stringifiedObjectReference"":""""
  },
  ""preProcessRecipe"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""processEquipmentType"": """",
  ""processMainProcessDefinitionID"": {
    ""identifier"": ""EMI-MCI_AN01.00"",
    ""stringifiedObjectReference"":""""
  },
  ""processOperationPass"": ""2"",
  ""processRecipeID"": {
    ""identifier"": ""IBM.RCP_P02.00"",
    ""stringifiedObjectReference"":""""
  },
  ""measurementEquipmentID"": {
    ""identifier"": ""EQP_M_IBM02"",
    ""stringifiedObjectReference"":""""
  },
  ""strHashedInfoSeq"": [], 
  ""actualEndTime"": ""2023-10-24-16.01.58.161949"",
  ""reticleID"": {
    ""identifier"": ""RTCL_GTJ_001"",
    ""stringifiedObjectReference"":""""
  },
  ""measurementEquipmentArea"": """",
  ""technologyID"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""reticleIDs"": [
    {
      ""identifier"": ""RTCL_GTJ_001"",
      ""stringifiedObjectReference"":""""
    }
  ],
  ""lotComment"": """",
  ""actualStartTime"": ""2023-10-24-16.01.35.466290"",
  ""preProcessOperationNo"": """",
  ""fixtureID"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""processOperationNumber"": ""0020.00400"",
  ""waferIDByChambers"": [],
  ""processEquipmentID"": {
    ""identifier"": ""ACC-1001"",
    ""stringifiedObjectReference"":""""
  },
  ""processProcessDefinitionType"": ""Process"",
  ""measurementLogicalRecipe"": {
    ""identifier"": ""LR_M_IBM01.00"",
    ""stringifiedObjectReference"":""""
  },
  ""operationNumber"": ""0020.00400"",
  ""chamberIDs"": [],
  ""measurementProcessDefinitionID"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""carrierID"": {
    ""identifier"": ""CJBE003"",
    ""stringifiedObjectReference"":""""
  },
  ""preProcessEquipmentID"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""measurementEquipmentType"": """",
  ""productGroupID"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""requestUserID"": {
    ""identifier"": ""ZLH"",
    ""stringifiedObjectReference"":""""
  },
  ""operationName"": """",
  ""preProcessLogicalRecipe"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""batchID"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""dcDefID"": {
    ""identifier"": ""DCD_IBM01.00"",
    ""stringifiedObjectReference"":""""
  },
  ""collectionType"": ""Measurement"",
  ""logicalRecipe"": {
    ""identifier"": ""LR_P_IBM02.00"",
    ""stringifiedObjectReference"":""""
  },
  ""stage"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""preProcessProcessDefinitionID"": {
    ""identifier"": """",
    ""stringifiedObjectReference"":""""
  },
  ""moduleProcessDefinitionID"": {
    ""identifier"": ""MPD_IBM02.00"",
    ""stringifiedObjectReference"":""""
  },
  ""preProcessEquipmentType"": """",
  ""flowType"": """"
}
";
        private async void LoadData()
        {
            await LoadFabAsync();
            await LoadLdsAsync();
            await LoadDeparmentAsync();
            // 加载MES || SPC的数据
            await LoadDcItemAsync();
            // 加载MES || SPC的数据
            await LoadChamberAsync();

            await LoadProcessEntityAsync();
            await LoadRulebAsync();

            LoadJobContextKeySaveRequests();
        }

        #region 加载数据 
        private List<SPCRuleEntity> ruleEntities;
        private async Task LoadRulebAsync()
        {
            ruleEntities = await OrmFactory.SpcOracle.Select<SPCRuleEntity>().Where(m => m.RULE_STATUS == "Active").ToListAsync();
        }
        private async Task LoadFabAsync()
        {
            var fabList = await OrmFactory.SpcOracle.Select<SPCFabEntity>().ToListAsync();
            this.cboFab.DisplayMember = "FAB_NAME";
            this.cboFab.DataSource = fabList;
        }

        private List<EnvSettingEntity> envSettingEntities = null;
        private async Task LoadEnvAsync()
        {
            envSettingEntities = await OrmFactory.MySqllite.Select<EnvSettingEntity>().ToListAsync();
            this.cboEnv.DisplayMember = "Name";
            this.cboEnv.DataSource = envSettingEntities;
        }
        private async Task LoadLdsAsync()
        {
            var ldsList = await OrmFactory.SpcOracle.Select<SPCLdsEntity>().ToListAsync();
            this.cboLds.DisplayMember = "NAME";
            this.cboLds.DataSource = ldsList;
        }

        private async Task LoadDeparmentAsync()
        {
            // Deleted
            var deparmentList = await OrmFactory.SpcOracle.Select<SPCDeparmentEntity>().Where(m => m.DATA_STATUS == "Active").ToListAsync();
            this.cboDeparment.DisplayMember = "MODULE_GROUP_NAME";
            this.cboDeparment.DataSource = deparmentList;
        }

        private List<MESChamberEntity> chamebrList = null;
        private async Task LoadChamberAsync()
        {
            txtSpcChamber.Text = "";
            checkChamber.Items.Clear();
            if (checkDataCollection.Checked)
            {// 获取spc的数据

                checkChamber.Enabled = false;
                txtSpcChamber.Enabled = true;
            }
            else
            {
                checkChamber.Enabled = true;
                txtSpcChamber.Enabled = false;

                chamebrList = await OrmFactory.MesOracle.Select<MESChamberEntity>().ToListAsync();
                var array = chamebrList.Select(m => m.CHAMBER_ID).ToArray();
                checkChamber.Items.AddRange(array);
            }
        }

        private async Task LoadDcItemAsync()
        {
            txtChartControlItem.Text = "";
            txtSpcControlItem.Text = "";
            checkMESDcitem.Items.Clear();
            multipleDcItem.Items.Clear();

            if (checkDataCollection.Checked)
            {// 获取spc的数据

                txtChartControlItem.Enabled = true;
                txtSpcControlItem.Enabled = true;

                multipleDcItem.Enabled = false;
                checkMESDcitem.Enabled = false;

            }
            else
            {  // 获取mes的数据
                txtChartControlItem.Enabled = false;
                txtSpcControlItem.Enabled = false;

                multipleDcItem.Enabled = true;
                checkMESDcitem.Enabled = true;
                var dcItemList = await OrmFactory.MesOracle.Select<MESDcItemEntity>()
                                                  .Where(m => !m.DCITEM_NAME.Contains("W_") && !m.DCITEM_NAME.Contains("L_"))
                                                  .Distinct()
                                                  .ToListAsync();
                var array = dcItemList.Select(m => m.DCITEM_NAME).ToArray();
                multipleDcItem.Items.AddRange(array);
                checkMESDcitem.Items.AddRange(array);

                // 横向展示
                // multipleDcItem.MultiColumn = true;
            }
        }
        List<SPCContextKeyEntity> allContextKey;
        private async void CboLds_SelectedValueChanged(object? sender, EventArgs e)
        {
            if (cboLds.SelectedItem != null)
            {
                var ldsEntity = cboLds.SelectedItem as SPCLdsEntity;
                if (ldsEntity != null)
                {
                    await LoadContextKeyAsync(ldsEntity.COLLECT_TYPE);
                    await LoadSubFolderAsync(ldsEntity.ID, ldsEntity.NAME);
                    await LoadOcapAsync(ldsEntity.COLLECT_TYPE);

                    allContextKey = await OrmFactory.SpcOracle.Select<SPCContextKeyEntity>().Where(m => m.COLLECT_TYPE == ldsEntity.COLLECT_TYPE).ToListAsync();
                    SetJson();
                }
            }
        }
        private async Task LoadOcapAsync(string lds)
        {
            this.cboOcap.Items.Clear();
            var envSettingEntity = this.cboEnv.SelectedItem as EnvSettingEntity;
            if (envSettingEntity != null)
            {
                var list = await OrmFactory.MySqllite.Queryable<OCAPTemplateEntity>()
                                                     .Where(m => m.EnvName == envSettingEntity.Name && m.Lds.ToUpper() == lds.ToUpper())
                                                     .ToListAsync();
                if (list != null)
                {
                    this.cboOcap.Items.AddRange(list.Select(m => m.FlowCode).ToArray());
                }
            }
        }

        private async Task LoadContextKeyAsync(string collectType)
        {
            contextKeyList = await OrmFactory.SpcOracle.Select<SPCContextKeyEntity>().Where(m => m.COLLECT_TYPE == collectType && m.KEY_TYPE == 0 && !m.KEY_NAME.Contains("GenericMKey")).ToListAsync();
            this.cboContextKey.DisplayMember = "KEY_NAME";
            this.cboContextKey.DataSource = contextKeyList;
        }

        private async Task LoadSubFolderAsync(long ldsId, string ldsName)
        {
            treeSubFolder.Nodes.Clear();
            var folderList = await OrmFactory.SpcOracle.Select<SPCSubFolderEntity>().Where(m => m.LDS_ID == ldsId).OrderBy(m => m.SORT).ToListAsync();

            TreeNode rootNode = new TreeNode(ldsName);
            treeSubFolder.Nodes.Add(rootNode);

            var childers = folderList.Where(m => m.PARENT_ID != 0).ToList();
            foreach (var pNode in folderList.Where(m => m.PARENT_ID == 0 && m.NAME != "Exclude List" && m.NAME != "Search Group" && m.NAME != "Matching"))
            {
                // 第一级
                TreeNode tnode = new TreeNode(pNode.NAME);
                tnode.Tag = pNode.ID;
                rootNode.Nodes.Add(tnode);

                LoadTree(childers, pNode.ID, tnode);
            }
            treeSubFolder.ExpandAll();
        }

        void LoadTree(List<SPCSubFolderEntity> allList, long pId, TreeNode parentNode)
        {
            var list = allList.Where(m => m.PARENT_ID == pId);
            foreach (var item in list)
            {
                TreeNode tnode = new TreeNode(item.NAME);
                tnode.Tag = item.ID;
                parentNode.Nodes.Add(tnode);

                var any = allList.Where(m => m.PARENT_ID == item.ID).Any();
                if (any)
                {
                    LoadTree(allList, item.ID, tnode);
                }
            }
        }

        #endregion

        #region 加载排除数据

        /// <summary>
        /// 加载列
        /// </summary>
        private void LoadColumn()
        {
            DataGridViewTextBoxColumn envNameBoxColumn = new DataGridViewTextBoxColumn();
            envNameBoxColumn.ReadOnly = true;
            envNameBoxColumn.Name = "Key";
            envNameBoxColumn.HeaderText = "Masert Key";
            envNameBoxColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            envNameBoxColumn.DataPropertyName = "Key";
            dgvExclude.Columns.Add(envNameBoxColumn);

            DataGridViewTextBoxColumn valueBoxColumn = new DataGridViewTextBoxColumn();
            valueBoxColumn.ReadOnly = false;
            valueBoxColumn.Name = "Value";
            valueBoxColumn.HeaderText = "值";
            valueBoxColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            valueBoxColumn.DataPropertyName = "Value";
            dgvExclude.Columns.Add(valueBoxColumn);

            DataGridViewButtonColumn delBoxColumn = new DataGridViewButtonColumn();
            delBoxColumn.ReadOnly = true;
            delBoxColumn.Name = "Delete";
            delBoxColumn.HeaderText = "操作";
            delBoxColumn.Width = 100;
            delBoxColumn.DefaultCellStyle.NullValue = "删除";
            dgvExclude.Columns.Add(delBoxColumn);
        }

        private List<KeyValues> keyValueList = new List<KeyValues>();
        private async void cboContextKey_SelectedValueChanged(object sender, EventArgs e)
        {
            cboKeyValue.Items.Clear();

            if (cboContextKey.SelectedItem != null && !this.checkDataCollection.Checked)
            {
                var contextKeyEntity = cboContextKey.SelectedItem as SPCContextKeyEntity;
                switch (contextKeyEntity.KEY_NAME)
                {
                    case "LotType":
                        var lotTypeList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT LOT_TYPE FROM FRLOTTYPE");
                        cboKeyValue.Items.AddRange(lotTypeList.ToArray());
                        break;

                    case "Area":
                        var areaList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT CODE_ID FROM FRCODE WHERE CATEGORY_ID = 'Department'");
                        cboKeyValue.Items.AddRange(areaList.ToArray());
                        break;

                    case "DCID":
                        var dcsidList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  DCDEF_ID  FROM FRDCDEF");
                        cboKeyValue.Items.AddRange(dcsidList.ToArray());
                        break;

                    case "Technology":
                        var technologyList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  TECH_ID  FROM FRTECH");
                        cboKeyValue.Items.AddRange(technologyList.ToArray());
                        break;

                    case "ProductGroup":
                        var productGroupList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  PRODGRP_ID FROM FRPRODGRP");
                        cboKeyValue.Items.AddRange(productGroupList.ToArray());
                        break;

                    case "Product":
                        var productList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  PRODSPEC_ID FROM FRPRODSPEC");
                        cboKeyValue.Items.AddRange(productList.ToArray());
                        break;

                    case "MainPD":
                        var mainPDList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  PD_ID FROM FRPRODSPEC FRPD WHERE PD_Level = 'Main'");
                        cboKeyValue.Items.AddRange(mainPDList.ToArray());
                        break;

                    case "Stage":
                        var stageList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  STAGE_ID FROM FRSTAGE");
                        cboKeyValue.Items.AddRange(stageList.ToArray());
                        break;

                    case "ModulePD":
                        var modulePDList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  PD_ID FROM FRPD PD_Level = 'Module'");
                        cboKeyValue.Items.AddRange(modulePDList.ToArray());
                        break;

                    case "ProcessPD":
                        var processPDList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  PD_ID FROM FRPD PD_Level = 'Operation' AND PD_TYPE = 'Process'");
                        cboKeyValue.Items.AddRange(processPDList.ToArray());
                        break;

                    case "ProcessRecipe":
                        var processRecipeList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct  RECIPE_ID FROM FRMRCP");
                        cboKeyValue.Items.AddRange(processRecipeList.ToArray());
                        break;

                    case "ProcessEquipment":
                        var processEquipmentList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct EQP_ID FREQP WHERE EQP_CATEGORY = 'Process'");
                        cboKeyValue.Items.AddRange(processEquipmentList.ToArray());
                        break;

                    case "ProcessEquipmentType":
                        var processEquipmentTypeList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct CODE_ID FRCODE WHERE CATEGORY_ID = 'Equipment Type'");
                        cboKeyValue.Items.AddRange(processEquipmentTypeList.ToArray());
                        break;

                    case "ProcessLogicRecipe":
                        var processLogicRecipeList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct LCRECIPE_ID  FROM FRLRCP WHERE RECIPE_TYPE = 'Process'");
                        cboKeyValue.Items.AddRange(processLogicRecipeList.ToArray());
                        break;

                    case "ProcessSubEquipment":
                        var processSubEquipmentList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct CHAMBER_ID  FROM CSFSRESOURCEMAP");
                        cboKeyValue.Items.AddRange(processSubEquipmentList.ToArray());
                        break;

                    case "MeasurePD":
                        var measurePDList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct FRPD  FROM FRPD WHERE PD_Level = 'Operation' AND PD_TYPE = 'Measurement'");
                        cboKeyValue.Items.AddRange(measurePDList.ToArray());
                        break;

                    case "MeasureRecipe":
                        var measureRecipeList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct RECIPE_ID FROM FRMRCP");
                        cboKeyValue.Items.AddRange(measureRecipeList.ToArray());
                        break;

                    case "MeasureEquipment":
                        var measureEquipmentList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct EQP_ID FROM FREQP WHERE EQP_CATEGORY = 'Measurement'");
                        cboKeyValue.Items.AddRange(measureEquipmentList.ToArray());
                        break;

                    case "MeasureEquipmentType":
                        var measureEquipmentTypeList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct CODE_ID FROM FRCODE WHERE CATEGORY_ID = 'Equipment Type'");
                        cboKeyValue.Items.AddRange(measureEquipmentTypeList.ToArray());
                        break;

                    case "MeasureLogicalRecipe":
                        var measureLogicalRecipeList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct LCRECIPE_ID FROM FRLRCP WHERE RECIPE_TYPE = 'Measurement'");
                        cboKeyValue.Items.AddRange(measureLogicalRecipeList.ToArray());
                        break;

                    case "ReticleID":
                        var reticleIDList = await OrmFactory.MesOracle.Ado.QueryAsync<string>("SELECT distinct DRBL_ID FROM FRDRBL WHERE DRBL_CATEGORY = 'Reticle'");
                        cboKeyValue.Items.AddRange(reticleIDList.ToArray());
                        break;
                    default:
                        break;
                }
            }
        }
        /// <summary>
        /// 自动排除
        /// </summary>
        private void LoadJobContextKeySaveRequests()
        {
            this.dgvExclude.DataSource = keyValueList;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(cboKeyValue.Text.Trim()))
            {
                MessageBox.Show("请输入值");
                return;
            }
            if (cboContextKey.SelectedItem == null)
            {
                MessageBox.Show("请选择MasterKey");
                return;
            }
            var contextKey = cboContextKey.SelectedItem as SPCContextKeyEntity;
            if (contextKey != null)
            {
                var keyValue = keyValueList.Where(m => m.Key == contextKey.KEY_NAME).FirstOrDefault();
                if (keyValue != null)
                {
                    keyValue.Value = cboKeyValue.Text.Trim();
                }
                else
                {
                    var contextKeyEntity = contextKeyList.Where(m => m.KEY_NAME == contextKey.KEY_NAME).FirstOrDefault();
                    if (contextKeyEntity != null)
                    {
                        keyValueList.Add(new KeyValues() { Key = contextKeyEntity.KEY_NAME, Value = cboKeyValue.Text.Trim(), ColumnIndex = contextKeyEntity.COLUMN_INDEX });
                    }
                }

                this.dgvExclude.DataSource = null;
                this.dgvExclude.DataSource = keyValueList;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DgvExclude_CellContentClick(object? sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (this.dgvExclude.Columns[e.ColumnIndex].Name == "Delete")
                {
                    //获取所在行的值
                    var key = dgvExclude.Rows[e.RowIndex].Cells["Key"].Value;
                    if (key != null)
                    {
                        var keyValue = keyValueList.Where(m => m.Key == key).FirstOrDefault();
                        if (keyValue != null)
                        {
                            var res = keyValueList.Remove(keyValue);
                            this.dgvExclude.DataSource = null;
                            this.dgvExclude.DataSource = keyValueList;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        #region 创建Job
        /// <summary>
        /// 创建job
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnBatchCreate_Click(object sender, EventArgs e)
        {
            #region 数据校验

            var envSettingEntity = this.cboEnv.SelectedItem as EnvSettingEntity;
            if (string.IsNullOrEmpty(cboFab.Text.Trim()))
            {
                MessageBox.Show("请填写Chart名称！"); return;
            }

            if (string.IsNullOrEmpty(txtChartName.Text.Trim()))
            {
                MessageBox.Show("请填写Chart名称！"); return;
            }
            if (string.IsNullOrEmpty(cboEdcLevel.Text.Trim()))
            {
                MessageBox.Show("请选择监控级别！"); return;
            }
            var fabEntity = this.cboFab.SelectedItem as SPCFabEntity;
            if (fabEntity == null)
            {
                MessageBox.Show("请选择车间/工厂！"); return;
            }
            if (cboLds.SelectedItem == null)
            {
                MessageBox.Show("请选择LDS！"); return;
            }

            if (treeSubFolder.SelectedNode == null)
            {
                MessageBox.Show("请选择Folder！"); return;
            }

            if (cboDeparment.SelectedItem == null)
            {
                MessageBox.Show("请选择部门！"); return;
            }

            if (checkDataCollection.Checked && string.IsNullOrEmpty(txtChartControlItem.Text.Trim()))
            {
                MessageBox.Show("请填写监控参数！"); return;
            }

            if (!checkDataCollection.Checked && multipleDcItem.CheckedItems.Count == 0)
            {
                MessageBox.Show("请选择监控参数！"); return;
            }

            if (keyValueList.Count == 0)
            {
                MessageBox.Show("请选择过滤参数！"); return;
            }

            if (checkHoldOCAP.Checked && cboOcap.SelectedItem == null)
            {// trigger OCAP
                MessageBox.Show("请选择触发OCAP Template！"); return;
            }
            #endregion

            var index = 0;
            var successCount = 0;
            var failCount = 0;
            var totalCount = (int)txtTotalChartCount.Value * multipleDcItem.CheckedItems.Count;
            var url = $"http://{envSettingEntity.Ip}:{envSettingEntity.Port}/mycim-spc-service/v1/rt-job/add";
            var jobAddDto = CreateJob(fabEntity.ID);

            if (checkDataCollection.Checked)
            {
                var dcItem = txtChartControlItem.Text.Trim();
                jobAddDto.chartInfo.controlItem = new ControlItem()
                {
                    variableControlItem = "V1",
                    variableDcItems = new List<string>() { dcItem },
                    attributeControlItem = "V1",
                    attributeDcItems = new List<string>() { dcItem }
                };
                for (int j = 0; j < txtTotalChartCount.Value; j++)
                {
                    index += 1;
                    jobAddDto.basicInfo.jobName = $"{txtChartName.Text.Trim()}-{dcItem}-{index}";
                    var res = await HttpClientHelper.HttpPostAsync<JobAddResponseDto>(url, ServiceLocator.TimeOut, jobAddDto);
                    if (res.code == 200)
                    {
                        successCount += 1;
                        UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount));
                    }
                    else if (res.code == 5000)
                    {// {"code":5000,"message":"JobNameExist","data":null}
                        failCount += 1;
                        UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount, false, res.message));
                    }
                    else
                    {
                        failCount += 1;
                        UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount, false, res.message));
                    }
                }
            }
            else
            {
                for (int i = 0; i < multipleDcItem.CheckedItems.Count; i++)
                {
                    var dcItem = multipleDcItem.CheckedItems[i].ToString();
                    jobAddDto.chartInfo.controlItem = new ControlItem()
                    {
                        variableControlItem = "V1",
                        variableDcItems = new List<string>() { dcItem },
                        attributeControlItem = "V1",
                        attributeDcItems = new List<string>() { dcItem }
                    };
                    for (int j = 0; j < txtTotalChartCount.Value; j++)
                    {
                        index += 1;
                        jobAddDto.basicInfo.jobName = $"{txtChartName.Text.Trim()}-{dcItem}-{index}";
                        var res = await HttpClientHelper.HttpPostAsync<JobAddResponseDto>(url, ServiceLocator.TimeOut, jobAddDto);
                        if (res.code == 200)
                        {
                            successCount += 1;
                            UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount));
                        }
                        else if (res.code == 5000)
                        {// {"code":5000,"message":"JobNameExist","data":null}
                            failCount += 1;
                            UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount, false, res.message));
                        }
                        else
                        {
                            failCount += 1;
                            UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount, false, res.message));
                        }
                    }
                }
            }
            for (int i = 0; i < multipleDcItem.CheckedItems.Count; i++)
            {
                var dcItem = multipleDcItem.CheckedItems[i].ToString();
                jobAddDto.chartInfo.controlItem = new ControlItem()
                {
                    variableControlItem = "V1",
                    variableDcItems = new List<string>() { dcItem },
                    attributeControlItem = "V1",
                    attributeDcItems = new List<string>() { dcItem }
                };
                for (int j = 0; j < txtTotalChartCount.Value; j++)
                {
                    index += 1;
                    jobAddDto.basicInfo.jobName = $"{txtChartName.Text.Trim()}-{dcItem}-{index}";
                    var res = await HttpClientHelper.HttpPostAsync<JobAddResponseDto>(url, ServiceLocator.TimeOut, jobAddDto);
                    if (res.code == 200)
                    {
                        successCount += 1;
                        UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount));
                    }
                    else if (res.code == 5000)
                    {// {"code":5000,"message":"JobNameExist","data":null}
                        failCount += 1;
                        UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount, false, res.message));
                    }
                    else
                    {
                        failCount += 1;
                        UtilEvents.Defaut.GetEvent<AddChartEvent>().Publish(new AddChartEventArgs(index, jobAddDto, totalCount, successCount, failCount, false, res.message));
                    }
                }
            }
        }

        private JobAddRequestDto CreateJob(long fabId)
        {
            JobAddRequestDto jobAddDto = new JobAddRequestDto();

            #region 封装建Char对象

            var ldsEntity = cboLds.SelectedItem as SPCLdsEntity;
            var subFolderId = treeSubFolder.SelectedNode.Tag.ToString();
            var deparmentEntity = cboDeparment.SelectedItem as SPCDeparmentEntity;

            jobAddDto.basicInfo = new BasicInfo()
            {
                ldsId = ldsEntity.ID.ToString(),
                spcFolderId = subFolderId,
                jobName = "",
                fabObjectId = fabId,
                moduleGroupId = deparmentEntity.ID,
                edcLevel = cboEdcLevel.Text,
                controlStatus = "SPC_CONTROL",
                jobStatus = "ACTIVE",
                autoCreatedSubJob = checkCreateSubJob.Checked,
                onlySubjob = !checkRule.Checked,
                normalizaTionModelEnum = "NOTNORMALIZATION",
                movingChartReset = "2024-01-01 00:00:00",
                collectionIntervalOccurs = false,
                inlineType = ldsEntity.COLLECT_TYPE,
                keyChart = checkKeyChart.Checked,
                alarmMailTypes = new List<string>() { "ALARM_OCCURS" },
                subJob = false,
                matchingInherit = false,
                autoSubJobInherit = false,
                mailTemplateInherit = false,
                collectionIntervalInherit = true,
                collectionIntervalTemplateInherit = false,
                subJobInherit = new SubJobInherit(),
                chartDisplayInherit = true,
                displayType = "1",
                showGraphics = "",
                effectiveDate = "2024-01-01 00:00:00",
                dataType = "Variable",
                gradeAlarmId = "",
                mailTemplate = "",
                mailChartPointNum = 25,
                mailTo = new MailTo() { groupIds = new List<string>(), userIds = new List<string>() },
                mailCc = new MailCc() { groupIds = new List<string>(), userIds = new List<string>() },
                collectionIntervalMailTo = null,
                collectionIntervalMailCc = null,
            };
            if (cboOcap.SelectedItem != null)
            {
                jobAddDto.basicInfo.ocapTemplateId = cboOcap.SelectedItem.ToString();
            }
            jobAddDto.jobContextKeySaveRequests = new List<JobContextKeySaveRequests>();
            foreach (var item in keyValueList)
            {
                jobAddDto.jobContextKeySaveRequests.Add(new JobContextKeySaveRequests() { columnIndex = item.ColumnIndex, value = item.Value });
            }
            jobAddDto.jobExcludeValueList = new List<string>();
            var screenConfig = new ScreenConfig()
            {
                uscrl = "1200",
                lscrl = "10",
            };

            jobAddDto.chartInfo = new ChartInfo()
            {
                unit = "-",
                outlier = new Outlier()
                {
                    lower = "-100",
                    upper = "1500",
                },
                chartTypes = new List<string>() { "XBAR", "TREND", "R", "S" },
                chartConfigs = new List<ChartConfigsItem>()
                    {
                        new ChartConfigsItem()
                        {
                            chartType="XBAR",
                            controlConfig = new ControlConfig()
                            {
                                    limitType =  "MANUAL",
                                    cl= txtCLForXbar.Text.Trim(),
                                    lcl=  txtLCLForXbar.Text.Trim(),
                                    ucl=  txtUCLForXbar.Text.Trim(),
                                    clDisable= false,
                                    lclDisable= false,
                                    uclDisable= false
                            },
                            specConfig = new SpecConfig()
                            {
                                limitType = checkStandardForXbar.Checked ? "Standard" : "MANUAL",
                                target = !checkStandardForXbar.Checked ? txtTargetForXbar.Text.Trim():"",
                                lsl= !checkStandardForXbar.Checked ? txtLSLForXbar.Text.Trim():"",
                                usl= !checkStandardForXbar.Checked ? txtUSLForXbar.Text.Trim():"",
                                lslDisable= false,
                                targetDisable= false,
                                uslDisable=false,
                            },
                             screenConfig = screenConfig,
                             warningLimit ="8",
                        },
                        new ChartConfigsItem()
                        {
                            chartType="TREND",
                            controlConfig = new ControlConfig()
                            {
                                limitType="MANUAL",
                                cl= txtCLForTREND.Text.Trim(),
                                lcl=  txtLCLForTREND.Text.Trim(),
                                ucl=  txtUCLForTREND.Text.Trim(),
                                clDisable= false,
                                lclDisable= false,
                                uclDisable= false
                            },
                            specConfig = new SpecConfig()
                            {
                                limitType = checkStandardForTREND.Checked ? "Standard" : "MANUAL",
                                target = !checkStandardForTREND.Checked ? txtTargetForTREND.Text.Trim():"",
                                lsl= !checkStandardForTREND.Checked ? txtLSLForTREND.Text.Trim():"",
                                usl= !checkStandardForTREND.Checked ? txtUSLForTREND.Text.Trim():"",
                                lslDisable= false,
                                targetDisable= false,
                                uslDisable=false,
                            },
                             screenConfig = screenConfig,
                              warningLimit ="8",
                        },
                        new ChartConfigsItem()
                        {
                            chartType="R",
                            controlConfig = new ControlConfig()
                            {
                                limitType="MANUAL",
                                cl= txtCLForR.Text.Trim(),
                                lcl=  txtLCLForR.Text.Trim(),
                                ucl=  txtUCLForR.Text.Trim(),
                                clDisable= false,
                                lclDisable= false,
                                uclDisable= false
                            },
                            specConfig = new SpecConfig()
                            {
                                limitType = checkStandardForR.Checked ? "Standard" : "MANUAL",
                                target = !checkStandardForR.Checked ? txtTargetForR.Text.Trim():"",
                                lsl= !checkStandardForR.Checked ? txtLSLForR.Text.Trim():"",
                                usl= !checkStandardForR.Checked ? txtUSLForR.Text.Trim():"",
                                lslDisable= false,
                                targetDisable= false,
                                uslDisable=false,
                            },
                             screenConfig = screenConfig,
                             warningLimit ="8",
                        },
                        new ChartConfigsItem()
                        {
                            chartType="S",
                            controlConfig = new ControlConfig()
                            {
                                    limitType="MANUAL",
                                    cl= txtCLForS.Text.Trim(),
                                    lcl=  txtLCLForS.Text.Trim(),
                                    ucl=  txtUCLForS.Text.Trim(),
                                    clDisable= false,
                                    lclDisable= false,
                                    uclDisable= false
                            },
                            specConfig = new SpecConfig()
                            {
                                limitType = checkStandardForS.Checked ? "Standard" : "MANUAL",
                                target = !checkStandardForS.Checked ? txtTargetForS.Text.Trim():"",
                                lsl= !checkStandardForS.Checked ? txtLSLForS.Text.Trim():"",
                                usl= !checkStandardForS.Checked ? txtUSLForS.Text.Trim():"",
                                lslDisable= false,
                                targetDisable= false,
                                uslDisable=false,
                            },
                            screenConfig = screenConfig,
                             warningLimit ="8",
                        },
                    },
            };

            var holdList = new List<RuleHoldActionItem>()
            {
                new RuleHoldActionItem() { equip="", holdAction = true, holdType="Hold Lot", caId = 301, }

            };

            if (checkHoldOCAP.Checked)
            {// trigger OCAP 
                holdList.Add(new RuleHoldActionItem()
                {
                    equip = "",
                    holdAction = true,
                    holdType = "OCAP",
                    caId = 307,
                });
            }

            var chartType = new ChartType()
            {
                XBAR = false,
                TREND = false,
                R = false,
                S = false
            };
            jobAddDto.ruleConfigInfo = new List<RuleConfigInfoItem>();
            foreach (var item in ruleEntities)
            {
                jobAddDto.ruleConfigInfo.Add(new RuleConfigInfoItem()
                {
                    chartType = chartType,
                    ruleObjectId = item.ID,
                    ruleCode = item.RULE_CODE,
                });
            }

            if (checkOOS.Checked)
            {
                var oos = ruleEntities.Where(m => m.RULE_CODE == "OOS").FirstOrDefault();
                jobAddDto.ruleConfigInfo.Add(new RuleConfigInfoItem()
                {
                    chartType = new ChartType()
                    {
                        XBAR = true,
                        TREND = false,
                        R = true,
                        S = true
                    },
                    ruleHoldAction = holdList,
                    ruleObjectId = oos.ID,
                    actionSwitch = true,
                    ocapFlowList = new List<string>(),
                    ruleCode = "OOS",
                });
            }

            if (checkOOW.Checked)
            {
                var oow = ruleEntities.Where(m => m.RULE_CODE == "OOW").FirstOrDefault();
                jobAddDto.ruleConfigInfo.Add(new RuleConfigInfoItem()
                {
                    chartType = new ChartType()
                    {
                        XBAR = true,
                        TREND = true,
                        R = true,
                        S = true
                    },
                    ruleHoldAction = holdList,
                    ruleObjectId = oow.ID,
                    actionSwitch = true,
                    ocapFlowList = new List<string>(),
                    ruleCode = "OOW",
                });
            }

            if (checkSOOS.Checked)
            {
                var soos = ruleEntities.Where(m => m.RULE_CODE == "SOOS" || m.RULE_CODE == "RawDataOOS").FirstOrDefault();
                if (soos != null)
                {
                    jobAddDto.ruleConfigInfo.Add(new RuleConfigInfoItem()
                    {
                        chartType = new ChartType()
                        {
                            XBAR = false,
                            TREND = true,
                            R = false,
                            S = false
                        },
                        ruleHoldAction = holdList,
                        ruleObjectId = soos.ID,
                        actionSwitch = true,
                        ocapFlowList = new List<string>(),
                        ruleCode = "SOOS",
                    });
                }
            }

            if (checkSOOW.Checked)
            {
                var soow = ruleEntities.Where(m => m.RULE_CODE == "SOOW").FirstOrDefault();
                if (soow != null)
                {
                    jobAddDto.ruleConfigInfo.Add(new RuleConfigInfoItem()
                    {
                        chartType = new ChartType()
                        {
                            XBAR = false,
                            TREND = true,
                            R = false,
                            S = false
                        },
                        ruleHoldAction = holdList,
                        ruleObjectId = soow.ID,
                        actionSwitch = true,
                        ocapFlowList = new List<string>(),
                        ruleCode = "SOOW",
                    });
                }
            }

            if (checkWE1.Checked)
            {
                var we1 = ruleEntities.Where(m => m.RULE_CODE == "WE1").FirstOrDefault();
                jobAddDto.ruleConfigInfo.Add(new RuleConfigInfoItem()
                {
                    chartType = new ChartType()
                    {
                        XBAR = true,
                        TREND = true,
                        R = true,
                        S = true
                    },
                    ruleHoldAction = holdList,
                    ruleObjectId = we1.ID,
                    actionSwitch = true,
                    ocapFlowList = new List<string>(),
                    ruleCode = "WE1",
                });
            }

            if (checkKeyChart.Checked)
            {
                jobAddDto.spcCdfList = new List<SpcCdfListItem>()
                {
                        new SpcCdfListItem(){ seqNo =1, name = "Key Chart", value="KEY(Y)", dataType="String"}
                };
            }

            jobAddDto.gradeAlarmList = new List<GradeAlarmListItem>()
            {
                new GradeAlarmListItem()
                {
                    id="",
                    alarmType="OOS",
                    alarmTools=new List<string>(){ "MAIL" },
                    alarmTo="95845",
                    alarmCc="14141",
                    alarmTemplateId=19063,
                    jobIdFlag=true
                },
                new GradeAlarmListItem()
                {
                    id="",
                    alarmType="OOC",
                    alarmTools=new List<string>(){ "MAIL" },
                    alarmTo="95845",
                    alarmCc="14141",
                    alarmTemplateId=19063,
                    jobIdFlag=true
                },
            };

            #endregion

            return jobAddDto;
        }

        /// <summary>
        /// 格式化Json
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnJson_Click(object sender, EventArgs e)
        {
            if (txtJson.Text.Trim().Length == 0)
            {
                MessageBox.Show("消息内容不可为空");
                return;
            }

            FormartJson();
        }
        private void FormartJson()
        {
            if (txtJson.Text.Trim().Length > 0)
            {
                try
                {
                    //JObject.ToString()方法会内部调用格式化，所以直接使用即可
                    string json = txtJson.Text.Trim();
                    //判读是数组还是对象
                    if (json.Trim().StartsWith("["))
                    {
                        JArray jobj = JArray.Parse(json);
                        txtJson.Text = jobj.ToString();
                    }
                    else if (json.Trim().StartsWith("{"))
                    {
                        JObject jobj = JObject.Parse(json);
                        txtJson.Text = jobj.ToString();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("错误的JSON");
                }
            }
        }

        /// <summary>
        /// 查看结果
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnShowResult_Click(object sender, EventArgs e)
        {
            var frmAddChartResult = new FrmAddChartResult();
            frmAddChartResult.ShowDialog();
        }

        /// <summary>
        /// 校验MES数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDataCheck_Click(object sender, EventArgs e)
        {

        }

        #endregion

        #region 保存模拟发送配置

        /// <summary>
        /// 预览
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLook_Click(object? sender, EventArgs e)
        {
            if (checkDataCollection.Checked)
            {
                MessageBox.Show("暂不支持");
            }
            else
            {
                txtDcItems.Text = BuildDcItems();
            }
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnSave_Click(object? sender, EventArgs e)
        {
            try
            {
                var envSettingEntity = this.cboEnv.SelectedItem as EnvSettingEntity;
                if (envSettingEntity == null)
                {
                    MessageBox.Show("请选择环境！"); return;
                }
                if (string.IsNullOrEmpty(txtName.Text))
                {
                    MessageBox.Show("请输入名称！"); return;
                }

                if (checkRandom.Checked && txtLower.Value == 0 && txtUpper.Value == 0)
                {
                    MessageBox.Show("请填写随机生成原始值区间！"); return;
                }
                if (checkRandom.Checked && txtLower.Value >= txtUpper.Value)
                {
                    MessageBox.Show("随机生成原始值区间有误！"); return;
                }
                if (checkDataCollection.Checked && string.IsNullOrEmpty(txtSpcControlItem.Text.Trim()))
                {
                    MessageBox.Show("请填写监控参数！"); return;
                }

                if (!checkDataCollection.Checked && checkMESDcitem.CheckedItems.Count == 0)
                {
                    MessageBox.Show("请选择监控参数！"); return;
                }
                var lds = cboLds.SelectedItem as SPCLdsEntity;
                var msg = txtJson.Text;
                //if (!string.IsNullOrEmpty(txtSpcControlItem.Text.Trim()))
                //{
                //    msg = msg.Replace("{{dcItemName}}", txtSpcControlItem.Text.Trim());
                //}

                var processEntity = new ProcessEntity()
                {
                    Name = txtName.Text,
                    BasicInfo = msg,
                    DcItemCount = checkDataCollection.Checked ? 1 : checkMESDcitem.CheckedItems.Count,
                    EvnName = envSettingEntity.Name,
                    RawDataCount = (int)txtRawDataCount.Value,
                    RawDataRandom = checkRandom.Checked,
                    ContinueUni = cboContinueUni.SelectedItem.ToString(),
                    ContinueCount = (int)txtContinueCount.Value,
                    UserCount = (int)txtUserCount.Value,
                    WaferCount = (int)txtWaferCount.Value,
                    Second = txtSecond.Value,
                    SecondCount = (int)txtSecondCount.Value,
                    Lower = (int)txtLower.Value,
                    Upper = (int)txtUpper.Value,
                    RuleOOCoos = txtRuleOOCOOS.Value,
                    BuildOtherDcItem = cboBuidOtherDcItem.Checked,
                    CheckDataCollection = checkDataCollection.Checked,
                    LdsName = lds.NAME
                };

                var random = new Random();
                var chamberTmplate = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";

                if (checkDataCollection.Checked && !string.IsNullOrEmpty(txtSpcChamber.Text.Trim()))
                {
                    processEntity.Chambers = txtSpcChamber.Text.Trim();
                }
                else if (!checkDataCollection.Checked && checkChamber.CheckedItems.Count > 0)
                {
                    for (int i = 0; i < checkChamber.CheckedItems.Count; i++)
                    {
                        processEntity.Chambers += checkChamber.CheckedItems[i].ToString() + ",";

                        var chamberEntity = chamebrList.Where(m => m.CHAMBER_ID == checkChamber.CheckedItems[i].ToString()).FirstOrDefault();
                        if (chamberEntity != null)
                        {
                            StringBuilder sb = new StringBuilder(chamberTmplate);
                            sb[chamberEntity.SEQ] = '_';
                            sb = sb.Replace("_", chamberEntity.REPRESENTATION_ID);
                            processEntity.ChamebrStrs += sb.ToString() + ",";
                        }
                    }
                }

                if (processEntity.Chambers != null)
                {
                    if (processEntity.Chambers.Length > 0)
                    {
                        processEntity.Chambers = processEntity.Chambers.Trim(',');
                    }
                }

                if (checkDataCollection.Checked && !string.IsNullOrEmpty(txtSpcControlItem.Text.Trim()))
                {
                    processEntity.DcItems = txtSpcControlItem.Text.Trim();
                }
                else if (!checkDataCollection.Checked && checkMESDcitem.CheckedItems.Count > 0)
                {
                    for (int i = 0; i < checkMESDcitem.CheckedItems.Count; i++)
                    {
                        processEntity.DcItems += checkMESDcitem.CheckedItems[i].ToString() + ",";
                    }
                    if (processEntity.DcItems.Length > 0)
                    {
                        processEntity.DcItems = processEntity.DcItems.Trim(',');
                    }
                }

                var process = await OrmFactory.MySqllite.Select<ProcessEntity>().Where(m => m.Name == processEntity.Name).FirstAsync();
                if (process != null)
                {// 修改
                    processEntity.Id = process.Id;
                    var updateRes = await OrmFactory.MySqllite.Update<ProcessEntity>().SetSource(processEntity).ExecuteAffrowsAsync();
                    if (updateRes > 0)
                    {
                        MessageBox.Show("修改成功");
                        await this.LoadProcessEntityAsync();
                    }
                    else
                    {
                        MessageBox.Show("修改失败");
                    }
                }
                else
                {// 新增
                    var insertRes = await OrmFactory.MySqllite.Insert<ProcessEntity>(processEntity).ExecuteAffrowsAsync();
                    if (insertRes > 0)
                    {
                        MessageBox.Show("新增成功");
                        await this.LoadProcessEntityAsync();
                    }
                    else
                    {
                        MessageBox.Show("新增失败");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"系统异常【{ex.Message}】");
            }
        }

        private List<ProcessEntity> processEntities = new List<ProcessEntity>();
        /// <summary>
        /// 加载表格数据
        /// </summary>
        /// <returns></returns>
        private async Task LoadProcessEntityAsync()
        {
            processEntities = await OrmFactory.MySqllite.Queryable<ProcessEntity>().ToListAsync();
            this.dgvProcess.DataSource = processEntities;
        }

        private void dgvProcess_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (this.dgvProcess.Columns[e.ColumnIndex].Name != "Delete")
            {
                var id = dgvProcess.Rows[e.RowIndex].Cells["Id"].Value?.ToString();
                var processEntity = processEntities.Where(m => m.Id == int.Parse(id)).FirstOrDefault();
                txtName.Text = processEntity.Name;
                txtJson.Text = processEntity.BasicInfo;

                cboEnv.SelectedItem = envSettingEntities.Where(m => m.Name == processEntity.EvnName).FirstOrDefault();
                txtRawDataCount.Value = processEntity.RawDataCount;
                checkRandom.Checked = processEntity.RawDataRandom;
                txtContinueCount.Value = processEntity.ContinueCount;
                cboContinueUni.SelectedItem = processEntity.ContinueUni;
                txtUserCount.Value = processEntity.UserCount;
                txtWaferCount.Value = processEntity.WaferCount;
                txtSecondCount.Value = processEntity.SecondCount;
                checkDataCollection.Checked = processEntity.CheckDataCollection;

                if (processEntity.Second == null || processEntity.Second <= 0)
                {
                    txtSecond.Value = (decimal)0.1;
                }
                else
                {
                    txtSecond.Value = processEntity.Second;
                }

                if (checkRandom.Checked)
                {
                    txtLower.Value = processEntity.Lower;
                    txtUpper.Value = processEntity.Upper;
                }

                if (processEntity.RuleOOCoos != null)
                {
                    txtRuleOOCOOS.Value = processEntity.RuleOOCoos;
                }
                if (processEntity.BuildOtherDcItem != null)
                {
                    cboBuidOtherDcItem.Checked = processEntity.BuildOtherDcItem;
                }

                if (processEntity.DcItems != null)
                {
                    txtSpcControlItem.Text = "";
                    if (processEntity.CheckDataCollection)
                    {
                        txtDcItemCount.Text = "1";
                        txtSpcControlItem.Text = processEntity.DcItems;
                        txtSpcControlItem.Enabled = true;
                        checkMESDcitem.Enabled = false;
                    }
                    else
                    {
                        txtSpcControlItem.Enabled = false;
                        checkMESDcitem.Enabled = true;
                        var dcItems = processEntity.DcItems.Split(",").ToList();
                        for (int i = 0; i < checkMESDcitem.Items.Count; i++)
                        {
                            if (dcItems.Any(m => m == checkMESDcitem.Items[i].ToString()))
                            {
                                checkMESDcitem.SetItemChecked(i, true);
                            }
                        }

                        txtDcItemCount.Text = dcItems.Count.ToString();
                    }
                }

                if (processEntity.Chambers != null)
                {
                    txtSpcChamber.Text = "";
                    if (processEntity.CheckDataCollection)
                    {
                        txtChamberCount.Text = "1";
                        txtSpcChamber.Text = processEntity.Chambers;
                        checkChamber.Enabled = false;
                        txtSpcChamber.Enabled = true;
                    }
                    else
                    {
                        checkChamber.Enabled = true;
                        txtSpcChamber.Enabled = false;
                        var chambers = processEntity.Chambers.Split(",").ToList();
                        for (int i = 0; i < checkChamber.Items.Count; i++)
                        {
                            if (chambers.Any(m => m == checkChamber.Items[i].ToString()))
                            {
                                checkChamber.SetItemChecked(i, true);
                            }
                        }

                        txtChamberCount.Text = chambers.Count.ToString();
                    }
                }
            }
        }

        /// <summary>
        /// 点击删除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void dgvProcess_CellContentClick(object? sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (this.dgvProcess.Columns[e.ColumnIndex].Name == "Delete")
                {
                    //获取所在行的值
                    var id = int.Parse(dgvProcess.Rows[e.RowIndex].Cells["Id"].Value.ToString());
                    // 删除
                    var deleteRes = await OrmFactory.MySqllite.Delete<ProcessEntity>().Where(m => m.Id == id).ExecuteAffrowsAsync();
                    if (deleteRes > 0)
                    {
                        MessageBox.Show("删除成功");
                        await this.LoadProcessEntityAsync();
                    }
                    else
                    {
                        MessageBox.Show("删除失败");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 加载列
        /// </summary>
        private void LoadProcessColumn()
        {
            DataGridViewTextBoxColumn idBoxColumn = new DataGridViewTextBoxColumn();
            idBoxColumn.ReadOnly = true;
            idBoxColumn.Name = "Id";
            idBoxColumn.HeaderText = "ID";
            idBoxColumn.DataPropertyName = "Id";
            dgvProcess.Columns.Add(idBoxColumn);

            DataGridViewTextBoxColumn envNameBoxColumn = new DataGridViewTextBoxColumn();
            envNameBoxColumn.ReadOnly = true;
            envNameBoxColumn.Name = "Name";
            envNameBoxColumn.HeaderText = "场景名称";
            envNameBoxColumn.DataPropertyName = "Name";
            dgvProcess.Columns.Add(envNameBoxColumn);

            DataGridViewTextBoxColumn evnNameBoxColumn = new DataGridViewTextBoxColumn();
            evnNameBoxColumn.ReadOnly = true;
            evnNameBoxColumn.Name = "EvnName";
            evnNameBoxColumn.HeaderText = "所属环境";
            evnNameBoxColumn.DataPropertyName = "EvnName";
            dgvProcess.Columns.Add(evnNameBoxColumn);

            DataGridViewButtonColumn delBoxColumn = new DataGridViewButtonColumn();
            delBoxColumn.ReadOnly = true;
            delBoxColumn.Name = "Delete";
            delBoxColumn.HeaderText = "操作";
            delBoxColumn.DefaultCellStyle.NullValue = "删除";
            dgvProcess.Columns.Add(delBoxColumn);
        }

        private string BuildDcItems()
        {
            // 数量
            var dcItemCount = checkDataCollection.Checked ? 1 : checkMESDcitem.CheckedItems.Count;
            var waferCount = txtWaferCount.Value;
            var rawDataCount = txtRawDataCount.Value;

            var str = new StringBuilder();

            var random = new Random();
            var ucl = int.Parse(txtUCLForXbar.Text);
            var cl = int.Parse(txtCLForXbar.Text);
            var chamberTmplate = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
            // 监控参数
            for (int a = 1; a <= dcItemCount; a++)
            {
                // wafer
                for (int b = 1; b <= waferCount; b++)
                {
                    // 量测点
                    for (int c = 1; c <= rawDataCount; c++)
                    {
                        str.AppendLine("{");

                        if (checkMESDcitem.CheckedItems.Count > 0)
                        {
                            str.AppendLine("\"dataItemName\": \"" + checkMESDcitem.CheckedItems[a - 1] + "\",");
                        }
                        else
                        {
                            str.AppendLine("\"dataItemName\": \"" + txtSpcControlItem.Text.Trim() + "\",");
                        }

                        str.AppendLine("\"siInfo\": { },");
                        str.AppendLine("\"waferPosition\": \"" + b + "\",");
                        str.AppendLine("\"specCheckResult\": \"0\",");

                        str.AppendLine("\"strHashedInfoSeq\": [{");
                        str.AppendLine("\"hashKey\": \"slotNo\",");
                        str.AppendLine("\"siInfo\": { },");
                        str.AppendLine("\"hashData\": \"" + b + "\"");
                        str.AppendLine("}],");

                        str.AppendLine("\"dataValue\": { },");
                        if (checkChamber.CheckedItems.Count > 0)
                        {
                            // 生成一个介于0到array.Length-1之间的随机索引值
                            var index = random.Next(checkChamber.CheckedItems.Count);
                            // 通过随机索引值访问数组中的元素
                            var chamber = checkChamber.CheckedItems[index];
                            var chamberEntity = chamebrList.Where(m => m.CHAMBER_ID == chamber).FirstOrDefault();
                            if (chamberEntity != null)
                            {
                                StringBuilder sb = new StringBuilder(chamberTmplate);
                                sb[chamberEntity.SEQ] = '_';
                                sb = sb.Replace("_", chamberEntity.REPRESENTATION_ID);
                                str.AppendLine("\"chamber_list\": \"" + sb.ToString() + "\",");
                            }
                            else
                            {
                                str.AppendLine("\"chamber_list\": \"" + chamber + "\",");
                            }
                        }
                        else
                        {

                            str.AppendLine("\"chamber_list\": \"" + txtSpcChamber.Text.Trim() + "\",");
                        }
                        str.AppendLine("\"reworkFlag\": \"N\",");

                        // 注意:不需要引号
                        if (checkRandom.Checked)
                        {
                            str.AppendLine("\"dataValueDouble\": " + random.Next(cl, ucl) + ",");
                        }
                        else
                        {
                            str.AppendLine("\"dataValueDouble\": " + (700 + random.Next(1, 99)) + ",");
                        }

                        str.AppendLine("\"targetValue\": 500,");
                        str.AppendLine("\"comment\": \"\",");
                        str.AppendLine("\"waferID\": \"PP000013-" + b + "\",");
                        str.AppendLine("\"sitePosition\": \"" + c + "\"");

                        if (a == dcItemCount && b == waferCount && c == rawDataCount)
                        {
                            str.AppendLine(" }");
                        }
                        else
                        {
                            str.AppendLine(" },");
                        }
                    }
                }
            }

            return str.ToString();
        }

        /// <summary>
        /// 选择dc item后计数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkMESDcitem_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if (checkDataCollection.Checked)
            {
                txtDcItemCount.Text = "1";
            }
            else
            {
                var number = 0;
                if (!string.IsNullOrEmpty(txtDcItemCount.Text))
                {
                    number = checkMESDcitem.CheckedItems.Count;// int.Parse(txtDcItemCount.Text);
                }

                if (e.NewValue == CheckState.Checked)
                {
                    number += 1;
                }
                if (e.NewValue == CheckState.Unchecked)
                {
                    if (number - 1 < 0)
                    {
                        number = 0;
                    }
                    else
                    {
                        number -= 1;
                    }
                }

                txtDcItemCount.Text = number.ToString();
            }
        }
        private void checkChamber_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if (checkDataCollection.Checked)
            {
                txtChamberCount.Text = "";
            }
            else
            {
                var number = 0;
                if (!string.IsNullOrEmpty(txtChamberCount.Text))
                {
                    number = int.Parse(txtChamberCount.Text);
                }

                if (e.NewValue == CheckState.Checked)
                {
                    number += 1;
                }
                if (e.NewValue == CheckState.Unchecked)
                {
                    if (number - 1 < 0)
                    {
                        number = 0;
                    }
                    else
                    {
                        number -= 1;
                    }
                }

                txtChamberCount.Text = number.ToString();
            }
        }
        #endregion

        #region 模拟发送

        /// <summary>
        /// 模拟发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnTest_Click(object sender, EventArgs e)
        {
            try
            {
                var envSettingEntity = this.cboEnv.SelectedItem as EnvSettingEntity;
                if (envSettingEntity == null)
                {
                    MessageBox.Show("请选择环境！"); return;
                }

                if (checkDataCollection.Checked && string.IsNullOrEmpty(txtSpcControlItem.Text.Trim()))
                {
                    MessageBox.Show("请填写监控参数！"); return;
                }

                if (!checkDataCollection.Checked && checkMESDcitem.CheckedItems.Count == 0)
                {
                    MessageBox.Show("请选择监控参数！"); return;
                }

                string message = string.Empty;
                if (checkDataCollection.Checked)
                {
                    message = await BuildHttpMessage();
                }
                else
                {
                    message = BuildCorbaMessage();
                }

                // 发送数据
                var url = $"http://{envSettingEntity.Ip}:{envSettingEntity.Port}/mycim-spc-check/spc/CorbaCallSpcCheck";
                if (checkDataCollection.Checked)
                {
                    url = $"http://{envSettingEntity.Ip}:{envSettingEntity.Port}/mycim-spc-check/spc/dynamicSpcCheck";
                    var res = await HttpClientHelper.HttpPostAsync<List<SpcHttpCheckResponseDto>>(url, ServiceLocator.TimeOut, message);
                    result = JsonConvert.SerializeObject(res);
                    if (res.code != 200)
                    {
                        MessageBox.Show($"Error-{res.code}-{res.message}");
                    }
                    else
                    {
                        var data = res.data.FirstOrDefault();
                        if (data != null)
                        {
                            if (data.errorCode == "11401")
                            {
                                MessageBox.Show($"Error-{data.errorCode}-{data.errorMessage}");
                            }
                            else if (data.errorCode == "0000")
                            {
                                MessageBox.Show($"{data.errorCode}-Success");
                            }
                        }
                    }
                }
                else
                {
                    var res = await HttpClientHelper.HttpPostAsync<SpcCheckResponseDto>(url, ServiceLocator.TimeOut, message);
                    result = JsonConvert.SerializeObject(res);
                    if (res.code != 200)
                    {
                        MessageBox.Show($"Error-{res.code}-{res.message}");
                    }
                    else
                    {
                        if (res.data.value != null)
                        {
                            if (res.data.value.txRC == "0000")
                            {
                                MessageBox.Show($"{res.code}-Success");
                            }
                            else if (res.data.value.txRC == "0001")
                            {
                                MessageBox.Show($"{res.data.value.txRC}-FUR没有按约定送Waferposition");
                            }
                            else if (res.data.value.txRC == "0002")
                            {
                                MessageBox.Show($"{res.data.value.txRC}-多个DCSID的Spec不一致");
                            }
                            else if (res.data.value.txRC == "1500")
                            {
                                MessageBox.Show($"{res.data.value.txRC}-系统异常");
                            }
                            else if (res.data.value.txRC == "1511")
                            {
                                MessageBox.Show($"{res.code}-没有匹配到Chart");
                            }
                            else if (res.data.value.txRC == "1512")
                            {
                                MessageBox.Show($"{res.data.value.txRC}-Spec跟Control的Limit校验失败");
                            }
                            else
                            {
                                MessageBox.Show($"Error-{res.code}-{res.message}");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"系统异常：【{ex.Message}】");
            }
        }
        private string BuildCorbaMessage()
        {
            // 基础数据
            var basicInfo = txtJson.Text;

            // 设置加工时间、量测时间
            var measurementTimestamp = DateTime.Now.ToString("yyyy-MM-dd.HH.mm.ss");
            var processTimestamp = DateTime.Now.AddHours(-2).ToString("yyyy-MM-dd.HH.mm.ss");
            basicInfo = basicInfo.Replace("{{measurementTimestamp}}", measurementTimestamp)
                                 .Replace("{{processTimestamp}}", processTimestamp);

            // 数量
            var dcItemCount = checkDataCollection.Checked ? 1 : checkMESDcitem.CheckedItems.Count;
            var waferCount = txtWaferCount.Value;
            var rawDataCount = txtRawDataCount.Value;

            var str = new StringBuilder();

            var random = new Random();

            var lower = (int)txtLower.Value;
            var upper = (int)txtUpper.Value;
            var chamberTmplate = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";

            //  违规率超过 30%  =  总量测点：3监控参数 * 3片数 * 17个点=153个点  * 0.3 = 45个样点违规：违规的点的数量
            var totalOOCOOSRawCount = rawDataCount * waferCount * txtRuleOOCOOS.Value;
            // 监控参数
            for (int a = 1; a <= dcItemCount; a++)
            {
                var oocoosCount = 0;
                // wafer
                for (int b = 1; b <= waferCount; b++)
                {
                    // 量测点
                    for (int c = 1; c <= rawDataCount; c++)
                    {
                        str.AppendLine("{");

                        if (checkMESDcitem.CheckedItems.Count > 0)
                        {
                            str.AppendLine("\"dataItemName\": \"" + checkMESDcitem.CheckedItems[a - 1] + "\",");
                        }
                        else
                        {
                            str.AppendLine("\"dataItemName\": \"" + txtSpcControlItem.Text.Trim() + "\",");
                        }

                        str.AppendLine("\"siInfo\": { },");
                        str.AppendLine("\"waferPosition\": \"" + b + "\",");
                        str.AppendLine("\"specCheckResult\": \"0\",");
                        //str.AppendLine("\"strHashedInfoSeq\": [],");

                        str.AppendLine("\"strHashedInfoSeq\": [{");
                        str.AppendLine("\"hashKey\": \"slotNo\",");
                        str.AppendLine("\"siInfo\": { },");
                        str.AppendLine("\"hashData\": \"" + b + "\"");
                        str.AppendLine("}],");

                        str.AppendLine("\"dataValue\": { },");

                        if (checkDataCollection.Checked && !string.IsNullOrEmpty(txtSpcChamber.Text.Trim()))
                        {
                            str.AppendLine("\"chamber_list\": \"" + txtSpcChamber.Text.Trim() + "\",");
                        }
                        else if (!checkDataCollection.Checked && checkChamber.CheckedItems.Count > 0)
                        {

                            // 生成一个介于0到array.Length-1之间的随机索引值
                            var index = random.Next(checkChamber.CheckedItems.Count);
                            // 通过随机索引值访问数组中的元素
                            var chamber = checkChamber.CheckedItems[index];
                            var chamberEntity = chamebrList.Where(m => m.CHAMBER_ID == chamber).FirstOrDefault();
                            if (chamberEntity != null)
                            {
                                StringBuilder sb = new StringBuilder(chamberTmplate);
                                sb[chamberEntity.SEQ] = '_';
                                sb = sb.Replace("_", chamberEntity.REPRESENTATION_ID);
                                str.AppendLine("\"chamber_list\": \"" + sb.ToString() + "\",");
                            }
                            else
                            {
                                str.AppendLine("\"chamber_list\": \"" + chamber + "\",");
                            }
                        }
                        else
                        {
                            str.AppendLine("\"chamber_list\": \"\",");
                        }


                        str.AppendLine("\"reworkFlag\": \"N\",");

                        // 注意:不需要引号
                        if (checkRandom.Checked)
                        {
                            if (oocoosCount < totalOOCOOSRawCount)
                            {
                                // 生成违规的数据
                                if (c % 3 == 0)
                                {
                                    str.AppendLine("\"dataValueDouble\": " + random.Next(upper, random.Next(upper, upper + 50)) + ",");
                                }
                                else
                                {
                                    str.AppendLine("\"dataValueDouble\": " + random.Next(random.Next(lower - 50, lower), lower) + ",");
                                }
                                oocoosCount++;
                            }
                            else
                            {
                                str.AppendLine("\"dataValueDouble\": " + random.Next(lower, upper) + ",");
                            }
                        }
                        else
                        {
                            str.AppendLine("\"dataValueDouble\": " + (700 + random.Next(1, 99)) + ",");
                        }

                        str.AppendLine("\"targetValue\": 500,");
                        str.AppendLine("\"comment\": \"\",");
                        str.AppendLine("\"waferID\": \"PP000013-" + b + "\",");
                        str.AppendLine("\"sitePosition\": \"" + c + "\"");
                        str.AppendLine(" },");
                    }
                }
            }


            #region MES计算好的数据
            if (cboBuidOtherDcItem.Checked)
            {
                var excludeDcItems = new List<string>();
                for (int a = 1; a <= dcItemCount; a++)
                {
                    excludeDcItems.Add($"L_{checkMESDcitem.CheckedItems[a - 1]}_STD");
                    excludeDcItems.Add($"L_{checkMESDcitem.CheckedItems[a - 1]}_MEAN");
                    excludeDcItems.Add($"L_{checkMESDcitem.CheckedItems[a - 1]}_RANGE");
                    excludeDcItems.Add($"L_{checkMESDcitem.CheckedItems[a - 1]}_UN");
                    excludeDcItems.Add($"W_{checkMESDcitem.CheckedItems[a - 1]}_STD");
                    excludeDcItems.Add($"W_{checkMESDcitem.CheckedItems[a - 1]}_MEAN");
                    excludeDcItems.Add($"W_{checkMESDcitem.CheckedItems[a - 1]}_RANGE");
                    excludeDcItems.Add($"W_{checkMESDcitem.CheckedItems[a - 1]}_UN");
                }

                for (int a = 1; a <= excludeDcItems.Count; a++)
                {
                    // wafer
                    for (int b = 1; b <= waferCount; b++)
                    {
                        // 量测点
                        for (int c = 1; c <= 1; c++)
                        {
                            str.AppendLine("{");
                            str.AppendLine("\"dataItemName\": \"" + excludeDcItems[a - 1] + "\",");
                            str.AppendLine("\"siInfo\": { },");
                            str.AppendLine("\"waferPosition\": \"" + b + "\",");
                            str.AppendLine("\"specCheckResult\": \"0\",");
                            str.AppendLine("\"strHashedInfoSeq\": [],");
                            str.AppendLine("\"dataValue\": { },");

                            if (checkDataCollection.Checked && !string.IsNullOrEmpty(txtSpcChamber.Text.Trim()))
                            {
                                str.AppendLine("\"chamber_list\": \"" + txtSpcChamber.Text.Trim() + "\",");
                            }
                            else if (!checkDataCollection.Checked && checkChamber.CheckedItems.Count > 0)
                            {
                                // 生成一个介于0到array.Length-1之间的随机索引值
                                var index = random.Next(checkChamber.CheckedItems.Count);
                                // 通过随机索引值访问数组中的元素
                                var chamber = checkChamber.CheckedItems[index];
                                var chamberEntity = chamebrList.Where(m => m.CHAMBER_ID == chamber).FirstOrDefault();
                                if (chamberEntity != null)
                                {
                                    StringBuilder sb = new StringBuilder(chamberTmplate);
                                    sb[chamberEntity.SEQ] = '_';
                                    sb = sb.Replace("_", chamberEntity.REPRESENTATION_ID);
                                    str.AppendLine("\"chamber_list\": \"" + sb.ToString() + "\",");
                                }
                                else
                                {
                                    str.AppendLine("\"chamber_list\": \"" + chamber + "\",");
                                }
                            }
                            else
                            {
                                str.AppendLine("\"chamber_list\": \"\",");
                            }


                            str.AppendLine("\"reworkFlag\": \"N\",");

                            // 注意:不需要引号
                            if (checkRandom.Checked)
                            {
                                str.AppendLine("\"dataValueDouble\": " + random.Next(lower, upper) + ",");
                            }
                            else
                            {
                                str.AppendLine("\"dataValueDouble\": " + (700 + random.Next(1, 99)) + ",");
                            }

                            str.AppendLine("\"targetValue\": 500,");
                            str.AppendLine("\"comment\": \"\",");
                            str.AppendLine("\"waferID\": \"PP000013-" + b + "\",");
                            str.AppendLine("\"sitePosition\": \"" + c + "\"");

                            if (a == excludeDcItems.Count && b == waferCount && c == 1)
                            {
                                str.AppendLine(" }");
                            }
                            else
                            {
                                str.AppendLine(" },");
                            }
                        }
                    }
                }
            }
            #endregion

            var message = basicInfo.Insert(basicInfo.Length - 2, $",\"dcItems\": [{str.ToString().TrimEnd(',')}]");
            return message;
        }

        private List<string> ProductList = new List<string>()
        {
            "AME-PLY-QC.00","WUM-PLY-QC.00","CAE-PLY-QC.00","POD-PLY-QC.00","UUO-PLY-QC.00","WEM-PLY-QC.00","IOD-PLY-QC.00","CIE-PLY-QC.00","ADC-PLY-QC.00","EMF-PLY-QC.00"
        };
        private async Task<string> BuildHttpMessage()
        {
            // 基础数据
            var basicInfo = txtJson.Text;
            var sampleDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            var measurementTimestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            var processTimestamp = DateTime.Now.AddHours(-2).ToString("yyyy-MM-dd HH:mm:ss");
            basicInfo = basicInfo.Replace("{{measurementTimestamp}}", measurementTimestamp)
                                 .Replace("{{processTimestamp}}", processTimestamp)
                                 .Replace("{{sampleDate}}", sampleDate)
                                 .Replace("{{dcItemName}}", txtSpcControlItem.Text.Trim());




            var random = new Random();
            basicInfo = basicInfo.Replace("{{product}}", ProductList[random.Next(ProductList.Count)]);

            // 数量
            var waferCount = txtWaferCount.Value;
            var rawDataCount = txtRawDataCount.Value;

            var str = new StringBuilder();
            var lower = (int)txtLower.Value;
            var upper = (int)txtUpper.Value;

            //  违规率超过 30%  =  总量测点：3监控参数 * 3片数 * 17个点=153个点  * 0.3 = 45个样点违规：违规的点的数量
            var totalOOCOOSRawCount = rawDataCount * waferCount * txtRuleOOCOOS.Value;
            // 监控参数

            var oocoosCount = 0;

            // wafer
            for (int b = 1; b <= waferCount; b++)
            {
                // 量测点
                for (int c = 1; c <= rawDataCount; c++)
                {
                    str.AppendLine("{");

                    if (checkRandom.Checked)
                    {
                        if (oocoosCount < totalOOCOOSRawCount)
                        {
                            // 生成违规的数据
                            if (c % 3 == 0)
                            {
                                str.AppendLine("\"dataValue\": \"" + random.Next(upper, random.Next(upper, upper + 50)) + "\",");
                            }
                            else
                            {
                                str.AppendLine("\"dataValue\": \"" + random.Next(random.Next(lower - 50, lower), lower) + "\",");
                            }
                            oocoosCount++;
                        }
                        else
                        {
                            str.AppendLine("\"dataValue\": \"" + random.Next(lower, upper) + "\",");
                        }
                    }
                    else
                    {
                        str.AppendLine("\"dataValue\": \"" + (700 + random.Next(1, 99)) + "\",");
                    }

                    var addedKeyRawValues = new StringBuilder();
                    var masterKeyRawValues = new StringBuilder();

                    foreach (var item in allContextKey.Where(m => m.KEY_TYPE == 0).OrderBy(m => m.COLUMN_INDEX))
                    {
                        if (item.KEY_NAME == "WaferID")
                        {
                            masterKeyRawValues.Append($"\"PP000013-{b}\",");
                        }
                        else if (item.KEY_NAME == "SitePosition")
                        {
                            masterKeyRawValues.Append($"\"{c}\",");
                        }
                        else
                        {
                            masterKeyRawValues.Append("\"\",");
                        }
                    }

                    foreach (var item in allContextKey.Where(m => m.KEY_TYPE != 0).OrderBy(m => m.COLUMN_INDEX))
                    {
                        if (item.KEY_NAME == "WaferID")
                        {

                            addedKeyRawValues.Append($"\"PP000013-{b}\",");
                        }
                        else if (item.KEY_NAME == "SitePosition")
                        {

                            addedKeyRawValues.Append($"\"{c}\",");
                        }
                        else
                        {
                            addedKeyRawValues.Append("\"\",");
                        }
                    }

                    str.AppendLine("\"masterKeys\": [" + masterKeyRawValues.ToString().TrimEnd(',') + "],");
                    str.AppendLine("\"addedKeys\": [" + addedKeyRawValues.ToString().TrimEnd(',') + "]");

                    str.AppendLine(" },");
                }
            }
            var message = basicInfo.Replace("{{rawValues}}", $"[{str.ToString().TrimEnd(',')}]");
            return message;
        }
        #endregion

        #region 更换环境

        private async void btnConn_Click(object sender, EventArgs e)
        {
            try
            {
                var envSettingEntity = this.cboEnv.SelectedItem as EnvSettingEntity;
                if (envSettingEntity != null)
                {
                    var initRes = await ResetFreeSql(envSettingEntity);
                    if (initRes == 0)
                    {// 成功、重新加载所有数据 
                        LoadUiData();
                        LoadData();
                        this.btnConn.Enabled = false;
                    }
                    else if (initRes == 1)
                    {// spc连接失败
                        MessageBox.Show("SPC数据库连接异常");
                    }
                    else if (initRes == 2)
                    {// mes连接失败
                        MessageBox.Show("MES数据库连接异常");
                    }
                    else
                    {// -1 异常
                        MessageBox.Show("数据库连接异常");
                    }
                }
                else
                {
                    MessageBox.Show("请选择数据库链接");
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error(ex.Message);
                MessageBox.Show("数据库连接异常");
            }
        }
        private void cboEnv_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.btnConn.Enabled = true;
        }
        public async Task<int> ResetFreeSql(EnvSettingEntity envSettingEntity)
        {
            // 拼接连接字符串(service Name 不行)
            var spcConnStr = string.Empty;
            var mesConnStr = string.Empty;

            if (envSettingEntity.SPCSidOrServiceName == "SID")
            {// SID
                spcConnStr = $"User ID={envSettingEntity.SPCAccount};Password={envSettingEntity.SPCPwd};Data Source=(DESCRIPTION = (ADDRESS_LIST= (ADDRESS = (PROTOCOL = TCP)(HOST = {envSettingEntity.SPCIp})(PORT = {envSettingEntity.SPCPort}))) (CONNECT_DATA = ({envSettingEntity.SPCSidOrServiceName} = {envSettingEntity.SPCSid})))";
                //spcConnStr = $"user id={envSettingEntity.SPCAccount};password={envSettingEntity.SPCPwd}; data source={envSettingEntity.SPCIp}:{envSettingEntity.SPCPort}:{envSettingEntity.SPCSid};Pooling=true;Min Pool Size=1 ";
            }
            else
            {// Service Name
                spcConnStr = $"user id={envSettingEntity.SPCAccount};password={envSettingEntity.SPCPwd}; data source={envSettingEntity.SPCIp}:{envSettingEntity.SPCPort}/{envSettingEntity.SPCSid};Pooling=true;Min Pool Size=1 ";
            }

            if (!string.IsNullOrEmpty(envSettingEntity.MESIp))
            {
                if (envSettingEntity.MESSidOrServiceName == "SID")
                {// SID
                    mesConnStr = $"User ID={envSettingEntity.MESAccount};Password={envSettingEntity.MESPwd};Data Source=(DESCRIPTION = (ADDRESS_LIST= (ADDRESS = (PROTOCOL = TCP)(HOST = {envSettingEntity.MESIp})(PORT = {envSettingEntity.MESPort}))) (CONNECT_DATA = ({envSettingEntity.MESSidOrServiceName}= {envSettingEntity.MESSid})))";
                    //mesConnStr = $"user id={envSettingEntity.MESAccount};password={envSettingEntity.MESPwd}; data source={envSettingEntity.MESIp}:{envSettingEntity.MESPort}:{envSettingEntity.MESSid};Pooling=true;Min Pool Size=1 ";
                }
                else
                {// Service Name
                    mesConnStr = $"user id={envSettingEntity.MESAccount};password={envSettingEntity.MESPwd}; data source={envSettingEntity.MESIp}:{envSettingEntity.MESPort}/{envSettingEntity.MESSid};Pooling=true;Min Pool Size=1 ";
                }
            }

            // 初始化DB
            return await OrmFactory.AddFreeSql(envSettingEntity.Name, mesConnStr, spcConnStr);
        }
        #endregion

        #region 消息详情

        private string result = string.Empty;
        private async void btnMsgDetail_Click(object sender, EventArgs e)
        {
            string message = string.Empty;
            if (checkDataCollection.Checked)
            {
                message = await BuildHttpMessage();
            }
            else
            {
                message = BuildCorbaMessage();
            }

            FrmSpcCheckMessage frmSpcCheckMessage = new FrmSpcCheckMessage(message, result);
            frmSpcCheckMessage.ShowDialog();
        }
        #endregion

        #region datacollection发送数据

        private async void checkDataCollection_CheckedChanged(object sender, EventArgs e)
        {
            if (checkDataCollection.Checked)
            {
                txtChartControlItem.Text = "";
                txtSpcChamber.Text = "";
                txtSpcControlItem.Text = "";
                
                txtChartControlItem.Enabled = true;
                txtSpcChamber.Enabled = true;
                txtSpcControlItem.Enabled = true;

                multipleDcItem.Enabled = false;
                checkMESDcitem.Enabled = false;
                checkChamber.Enabled = false;
            }
            else
            {
                txtChartControlItem.Text = "";
                txtSpcChamber.Text = "";
                txtSpcControlItem.Text = "";

                txtChartControlItem.Enabled = false;
                txtSpcChamber.Enabled = false;
                txtSpcControlItem.Enabled = false;

                multipleDcItem.Enabled = true;
                checkMESDcitem.Enabled = true;
                checkChamber.Enabled = true;
            }

            // 如果选中，使用datacollectionjson
            if (dgvProcess.SelectedRows.Count == 1)
            {
                SetJson();
            }
            else
            {
                if (checkDataCollection.Checked)
                {
                    this.txtJson.Text = httpJson;
                }
                else
                {
                    this.txtJson.Text = corbaJson;
                }

            }
        }

        private async void SetJson()
        {
            if (checkDataCollection.Checked && this.cboFab.SelectedItem != null && cboLds.SelectedItem != null)
            {
                var basicInfo = txtJson.Text;

                var fabEntity = this.cboFab.SelectedItem as SPCFabEntity;
                var ldsEntity = cboLds.SelectedItem as SPCLdsEntity;

                basicInfo = basicInfo.Replace("{{ldsId}}", ldsEntity.ID.ToString())
                                     .Replace("{{fabId}}", fabEntity.FAB_NAME);
                if (!string.IsNullOrEmpty(txtSpcControlItem.Text.Trim()))
                {
                    basicInfo = basicInfo.Replace("{{dcItemName}}", txtSpcControlItem.Text.Trim());
                }


                var addedKeys = new StringBuilder();
                var masterKeys = new StringBuilder();
                var mk = allContextKey.Where(m => m.KEY_TYPE == 0).OrderBy(m => m.COLUMN_INDEX).ToList();
                foreach (var item in mk)
                {
                    if (item.KEY_NAME == "WaferID")
                    {
                        masterKeys.Append("\".\",");
                    }
                    else if (item.KEY_NAME == "WaferPosition")
                    {
                        masterKeys.Append("\".\",");
                    }
                    else if (item.KEY_NAME == "SitePosition")
                    {
                        masterKeys.Append("\".\",");
                    }
                    else if (item.KEY_NAME == "MeasureTime")
                    {
                        masterKeys.Append("\"{{measurementTimestamp}}\",");
                    }
                    else if (item.KEY_NAME == "ProcessTime")
                    {
                        masterKeys.Append("\"{{processTimestamp}}\",");
                    }
                    else if (item.KEY_NAME == "Product")
                    {
                        masterKeys.Append("\"{{product}}\",");
                    }
                    else
                    {
                        masterKeys.Append($"\"{item.KEY_NAME}\",");
                    }
                }
                var ak = allContextKey.Where(m => m.KEY_TYPE != 0).OrderBy(m => m.COLUMN_INDEX).ToList();
                foreach (var item in ak)
                {
                    if (item.KEY_NAME == "WaferID")
                    {
                        addedKeys.Append("\".\",");
                    }
                    else if (item.KEY_NAME == "WaferPosition")
                    {
                        addedKeys.Append("\".\",");
                    }
                    else if (item.KEY_NAME == "SitePosition")
                    {
                        addedKeys.Append("\".\",");
                    }
                    else if (item.KEY_NAME == "MeasureTime")
                    {
                        addedKeys.Append("\"{{measurementTimestamp}}\",");
                    }
                    else if (item.KEY_NAME == "ProcessTime")
                    {
                        addedKeys.Append("\"{{processTimestamp}}\",");
                    }
                    else if (item.KEY_NAME == "Product")
                    {
                        addedKeys.Append("\"{{product}}\",");
                    }
                    else
                    {
                        addedKeys.Append($"\"{item.KEY_NAME}\",");
                    }
                }

                var addKey = addedKeys.ToString().Trim(',');
                var masterkey = masterKeys.ToString().Trim(',');

                txtJson.Text = basicInfo.Replace("{{addedKeys}}", addKey.TrimEnd(',')).Replace("{{masterKeys}}", masterkey.TrimEnd(','));
            }
        }
        #endregion
    }

    public class KeyValues
    {
        public string Key { get; set; }
        public string Value { get; set; }
        public int ColumnIndex { get; set; }
    }
}
